package com.touch.client.databank;
import static com.touch.client.databank.StringBank.CD;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Vector;
import javax.xml.parsers.ParserConfigurationException;
import org.xml.sax.SAXException;
import com.touch.core.util.XMLFile;
import com.touch.jgloo.JGLTextureLoader;
import com.touch.jgloo.core.JGLAnimationRules;
import com.touch.jgloo.owt.JGLAnimatedSprite;
public class SpriteBank 
{
	public static final Vector<BufferedImage> SPRITE_SHEETS = new Vector<BufferedImage>();
	public static final Vector<JGLAnimatedSprite> SPRITE = new Vector<JGLAnimatedSprite>();
	public static final HashMap<String, JGLAnimationRules> SPRITE_RULES = new HashMap<String, JGLAnimationRules>();
	public static String XML_SPRITES;
	public static void loadBank() throws MalformedURLException, SAXException, IOException, ParserConfigurationException
	{
		System.out.println("Loading sprite bank...");
		final XMLFile spriteInfo = new XMLFile(new URL(XML_SPRITES).openStream());					
		final int sheetCount = Integer.parseInt(spriteInfo.readValue("sprites", "sheets"));
		final int ruleCount = Integer.parseInt(spriteInfo.readValue("sprites", "rules", "count"));
		for(int index = 1; index <= ruleCount; index++)
		{
			boolean alt = false;
			try
			{
				final String ruleURL = spriteInfo.readURL(CD, "sprites", "rules", "rule" + index, "url");				
				final JGLAnimationRules animRules = new JGLAnimationRules(new URL(ruleURL).openStream());
				final String name = animRules.getName();				
				
				SpriteBank.SPRITE_RULES.put(name, animRules);
			}
			catch(final Exception defaultRuleException)
			{
				System.out.println("Error loading default rule!");
				System.out.println("Attempting to load rule from alternate location...");
				alt = true;					
			}						
			loadAlternateRule:
			{
				if(alt == false)
					break loadAlternateRule;
				try
				{
					final String ruleURL = spriteInfo.readURL(CD, "sprites", "rules", "rule" + index, "alt");				
					final JGLAnimationRules animRules = new JGLAnimationRules(new URL(ruleURL).openStream());
					final String name = animRules.getName();					
					SpriteBank.SPRITE_RULES.put(name, animRules);
				}
				catch(final Exception alternateRuleException)
				{
					System.out.println("Error loading alternative rule!");
					System.out.println("Attempting to continue execution...");
					alternateRuleException.printStackTrace();
				}
			}
		}
		for(int index = 1; index <= sheetCount; index++)
		{						
			final String sheetAlias = "sheet" + index;
			boolean alt = false;			
			try
			{				
				final String sheetLocation = spriteInfo.readURL(CD, "sprites", sheetAlias, "url");				
				final BufferedImage spriteSheet = JGLTextureLoader.processImage(new URL(sheetLocation).openStream());																
				final String style = spriteInfo.readValue("sprites", sheetAlias, "style");
				final JGLAnimationRules rule = SPRITE_RULES.get(style);
				final int width = Integer.parseInt(spriteInfo.readValue("sprites", sheetAlias, "sprite", "width"));
				final int height = Integer.parseInt(spriteInfo.readValue("sprites", sheetAlias, "sprite", "height"));				
				final String sprites = rule.getSprites();
				
				if(sprites.equals("sequential-y"))
					loadSequentialSprites(rule, spriteSheet, width, height);
				else
					loadSprite(rule, spriteSheet, width, height);
			}
			catch(final Exception defaultSheetException)
			{
				System.out.println("Error loading the sprite sheet from the default location!");
				System.out.println("Attempting to load the sprite sheet from the alternative location...");
				alt = true;				
			}				
			loadAlternateSheet:
			{
				if(alt == false)
					break loadAlternateSheet;
				try
				{
					final String sheetLocation = spriteInfo.readURL(CD, "sprites", sheetAlias, "alt");				
					final BufferedImage spriteSheet = JGLTextureLoader.processImage(new URL(sheetLocation).openStream());																
					final String style = spriteInfo.readValue("sprites", sheetAlias, "style");
					final JGLAnimationRules rule = SPRITE_RULES.get(style);
					final int width = Integer.parseInt(spriteInfo.readValue("sprites", sheetAlias, "sprite", "width"));
					final int height = Integer.parseInt(spriteInfo.readValue("sprites", sheetAlias, "sprite", "height"));				
					final String sprites = rule.getSprites();
					
					if(sprites.equals("sequential-y"))
						loadSequentialSprites(rule, spriteSheet, width, height);
					else
						loadSprite(rule, spriteSheet, width, height);
				}
				catch(Exception alternateSpriteException)
				{
					System.out.println("Error loading alternative sprite sheet!");
					System.out.println("Attempting to continue execution...");
					alternateSpriteException.printStackTrace();
				}
			}
		}	
	}
	private static void loadSequentialSprites(JGLAnimationRules rule, BufferedImage spriteSheet, int width, int height) 
	{	
		final int spriteCount = spriteSheet.getHeight() / height;
		final int sheetWidth = spriteSheet.getWidth();
		JGLAnimatedSprite sprite;
		SpriteBank.SPRITE_SHEETS.add(spriteSheet);
		for(int spriteIndex = 0; spriteIndex < spriteCount; spriteIndex++)
		{
			System.out.println("    Adding sprite part: " + (spriteIndex + 1) + "/" + spriteCount);
			sprite = new JGLAnimatedSprite();
			rule.applyToAnimatedSprite(sprite, spriteSheet.getSubimage(0, spriteIndex * height, sheetWidth, height), width, height);			
			SpriteBank.SPRITE.add(sprite);	
		}
	}
	private static void loadSprite(JGLAnimationRules rule, BufferedImage spriteSheet, int width, int height)
	{
		JGLAnimatedSprite sprite;
		sprite = new JGLAnimatedSprite();				
		rule.applyToAnimatedSprite(sprite, spriteSheet, width, height);			
		SpriteBank.SPRITE.add(sprite);	
		SpriteBank.SPRITE_SHEETS.add(spriteSheet);
	}
}